<template>
  <div>
    <draggable
      :list="imageList"
      tag="ul"
      item-key="url"
      :animation="300"
      class="el-upload-list"
      :class="[
        listType === 'picture' ? 'el-upload-list--picture' : 'el-upload-list--picture-card',
        { 'is-disabled': disabled }
      ]"
      @start="() => (dragging = true)"
      @end="() => (dragging = false)"
    >
      <template #item="{ element: file }">
        <li class="el-upload-list__item is-success">
          <div
            :class="listType === 'picture' ? ['w-32', 'h-32'] : ['w-full', 'h-full']"
            class="bg-gray-50 flex justify-center items-center relative"
          >
            <img class="max-w-full max-h-full block" :src="file.url" alt="" />
            <div
              class="full-flex-center absolute rounded-md cursor-move bg-black bg-opacity-50 opacity-0 space-x-4"
              :class="dragging ? undefined : 'hover:opacity-100'"
              @click.stop
            >
              <el-icon
                class="image-action"
                :title="$t('cms.imageCut')"
                @click="() => ((cropperVisible = true), (currentFile = file))"
                ><Crop
              /></el-icon>
              <el-icon
                class="image-action"
                :title="$t('cms.previewImage')"
                @click="() => handlePreview(file)"
                ><View
              /></el-icon>
              <el-icon
                class="image-action"
                :title="$t('cms.deleteImage')"
                @click="() => imageList.splice(imageList.indexOf(file), 1)"
                ><Delete
              /></el-icon>
            </div>
          </div>
          <div v-if="listType === 'picture'" class="ml-2">
            <el-input v-model="file.url" placeholder="URL" maxlength="255">
              <template #prepend>URL</template>
            </el-input>
            <el-input v-model="file.name" :placeholder="$t('cms.content.images.name')" class="mt-1">
              <template #prepend>{{ $t('cms.content.images.name') }}</template>
            </el-input>
            <el-input
              v-model="file.description"
              type="textarea"
              :rows="2"
              :placeholder="$t('cms.content.images.description')"
              class="mt-1"
            />
          </div>
        </li>
      </template>
      <template #footer>
        <el-upload
          :action="imageUploadUrl"
          :headers="uploadHeaders"
          :data="getData()"
          :accept="accept"
          :before-upload="beforeUpload"
          :on-success="
            (res: any, file: any) => imageList.push({ name: res.data.name, url: res.data.url })
          "
          :on-progress="(event: any, file: any) => (progressFile = file)"
          :on-error="onError"
          :show-file-list="false"
          :disabled="disabled"
          multiple
          drag
        >
          <el-progress
            v-if="progressFile.status === 'uploading'"
            type="circle"
            :percentage="parseInt(progressFile.percentage, 10)"
          />
          <div v-else class="el-upload--picture-card">
            <el-icon><Plus /></el-icon>
          </div>
        </el-upload>
      </template>
    </draggable>
    <!-- </transition-group> -->
    <div>
      <el-dialog v-model="previewVisible" top="5vh" :width="768">
        <el-input v-model="previewFile.url" maxlength="255">
          <template #prepend>URL</template>
        </el-input>
        <el-input
          v-if="listType !== 'picture'"
          v-model="previewFile.name"
          :placeholder="$t('cms.content.images.name')"
          class="mt-1"
        >
          <template #prepend>{{ $t('cms.content.images.name') }}</template>
        </el-input>
        <el-input
          v-if="listType !== 'picture'"
          v-model="previewFile.description"
          type="textarea"
          :rows="2"
          :placeholder="$t('cms.content.images.description')"
          class="mt-1"
        />
        <img :src="previewFile.url" alt="" class="mt-1 border border-gray-300" />
      </el-dialog>
    </div>
    <image-cropper
      v-model="cropperVisible"
      :src="currentFile.url"
      @success="(url) => (currentFile.url = url)"
    />
  </div>
</template>
<script setup lang="ts">
import { ref, toRefs, computed, watch, PropType } from 'vue'
import { ElMessage, useFormItem } from 'element-plus'
import { Plus, Crop, View, Delete } from '@element-plus/icons-vue'
import { useI18n } from 'vue-i18n'
import draggable from 'vuedraggable'
import { getAccessToken, getTenantId } from '@/utils/auth'
import { getSiteHeader } from '@/utils/cmscommon'
import { uploadSettings, imageUploadUrl } from '@/api/cms/upload/types'
import ImageCropper from './ImageCropper.vue'

const props = defineProps({
  modelValue: { type: Array, default: () => [] },
  fileAccept: { type: String, default: null },
  fileMaxSize: { type: Number, default: null },
  maxWidth: { type: Number, default: null },
  maxHeight: { type: Number, default: null },
  listType: { type: String as PropType<'pictureCard' | 'picture'>, default: 'pictureCard' },
  disabled: { type: Boolean, default: false }
})

const emit = defineEmits({ 'update:modelValue': null })
const { modelValue, maxWidth, maxHeight, fileAccept, fileMaxSize } = toRefs(props)
const { t } = useI18n()
const dragging = ref<boolean>(false)
const progressFile = ref<any>({})
const currentFile = ref<any>({})
const previewVisible = ref<boolean>(false)
const cropperVisible = ref<boolean>(false)
const previewFile = ref<any>({ src: 'data:;base64,=' })
const uploadHeaders = ref()
const imageList = computed({
  get: (): any[] => modelValue.value,
  set: (val: any) => emit('update:modelValue', val)
})
const { formItem } = useFormItem()
watch(
  imageList,
  () => {
    formItem?.validate?.('change').catch((err: any) => {
      if (import.meta.env.MODE !== 'production') {
        console.warn(err)
      }
    })
  },
  { deep: true }
)
const handlePreview = (file: any) => {
  previewFile.value = file
  previewVisible.value = true
}
const getData = () => {
  const data: any = { isWatermark: true }
  if (maxWidth?.value != null) {
    data.maxWidth = maxWidth.value
  }
  if (maxHeight?.value != null) {
    data.maxHeight = maxHeight.value
  }
  return data
}
const accept = computed(() => {
  const accepts = fileAccept?.value ?? uploadSettings.imageInputAccept
  return accepts
})
const maxSize = computed(() => fileMaxSize?.value ?? uploadSettings.imageLimitByte)
const beforeUpload = (file: any) => {
  if (maxSize.value > 0 && file.size > maxSize.value) {
    ElMessage.error(t('cms.error.fileMaxSize', { size: `${maxSize.value / 1024 / 1024} MB` }))
    return false
  }
  uploadHeaders.value = {
    Authorization: 'Bearer ' + getAccessToken(),
    'tenant-id': getTenantId(),
    'jprocms-site-id': getSiteHeader()
  }
  console.log('uploadHeaders->', uploadHeaders)

  return true
}
const onError = (error: Error) => {
  ElMessage.error(t('上传失败，请您重新上传！'))
  console.log(error)
}
</script>
<style lang="scss" scoped>
:deep(.el-dialog__headerbtn) {
  top: 4px;
}

.full-flex-center {
  @apply w-full h-full flex justify-center items-center;
}

.image-action {
  @apply cursor-pointer text-xl text-white;
}

:deep(.el-upload-dragger) {
  padding: 0;
}

:deep(.el-upload--picture-card) {
  border: 0;
}

:deep(.el-upload-list--picture-card .el-progress) {
  left: 0;
  transform: none;
}

:deep(.el-upload-list__item) {
  transition: none;
}
.img-full-flex-center{
  display: flex;
  height: 100%;
  width: 100%;
  align-items: center;
  justify-content: center;
}
.image-action {
  cursor: pointer;
  font-size: 1.25rem;
  line-height: 1.75rem;
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1))
}
</style>
